#include "my_hashmap.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

hashmap_t* hashmap_create(){
    hashmap_t* map = (hashmap_t*)malloc(sizeof(hashmap_t));
    map->len = 0;
    for(int i=0;i<20;i++){
        map->arr[i] = (node_t*)malloc(sizeof(node_t));
        map->arr[i]->subLen = 0;
        map->arr[i]->next = NULL;
    }
    return map;
}

void hashmap_destroy(hashmap_t* map){
    for(int i=0;i<20;i++){
        node_t* node = map->arr[i];
        node_t* p=node->next;
        for(int j=0;j<node->subLen;j++){
            node_t* temp=p;
            p=p->next;
            free(temp);
        }
        free(node);
    }
    free(map);
}

int hashmap_hashcode(char* key){
    int len = strlen(key);
    unsigned int value=0;
    for(int i=0;i<len;i++){
        value+=key[i];
    }
    return value%20;
}

void hashmap_put(hashmap_t* map, char* key, data_t value){
    //计算hashcode
    int hashcode = hashmap_hashcode(key);
    //判断该节点元素是否已经存储了
    data_t* temp = hashmap_get(map, key);
    printf("!!![111]::hashmap_put: addr1=[%p], addr2=[%p]\n",temp, &value);
    if(temp!=NULL){
        //已经存在，则更新内容
        memcpy(temp, &value, sizeof(data_t));
        return;
    }
    
    //
    node_t* head = map->arr[hashcode];
    node_t* p = (node_t*)malloc(sizeof(node_t));
    // p->data = value;
    memcpy(&(p->data), &value, sizeof(data_t));
    //
    p->next = head->next;
    head->next = p;
    head->subLen += 1;
    map->len += 1;
    printf("!!![222]::hashmap_put: addr1=[%p], addr2=[%p],addr3=[%p]\n",temp, &value, &(p->data));
}

data_t* hashmap_get(hashmap_t* map, char* key){
    int hashcode = hashmap_hashcode(key);
    node_t* head = map->arr[hashcode];
    node_t* p = head->next;
    for(int i=0;i<head->subLen;i++){
        if(strcmp(p->data.devid, key) == 0){
            return &(p->data);
        }
        p = p->next;
    }
    return NULL;
}

void hashmap_remove(hashmap_t* map, char* key){
    int hashcode = hashmap_hashcode(key);
    node_t* head = map->arr[hashcode];
    node_t* p = head->next, *pre=head;
    for(int i=0;i<head->subLen;i++){
        if(strcmp(p->data.devid, key) == 0){//找到要删除的节点了
            pre->next = p->next;
            free(p);
            head->subLen--;
            map->len--;
            return;
        }
        pre = p;
        p = p->next;
    }
}

int hashmap_size(hashmap_t* map){
    return map->len;
}

void hashmap_printself(hashmap_t* map){
    for(int i=0;i<20;i++){
        node_t* node = map->arr[i];
        node_t* p=node->next;
        for(int j=0;j<node->subLen;j++){
            //
            data_t data = p->data;
            printf("%s: hashcode=[%d],devid=[%s],devfd=[%d],userfd=[%d]\n", __func__, i, data.devid, data.devfd, data.userfd);
            printf("strlen(devid)=[%ld],addr=[%p],addr2=[%p]\n", strlen(data.devid), &data.devid, &data);
            for(int i=0;i<strlen(data.devid);i++)
                printf("%02X ", (unsigned char)data.devid[0]);
            printf("\n");
            //
            p=p->next;
        }
    }
}


//测试代码
// int main(){
//     hashmap_t* map = hashmap_create();

//     data_t data1={.devid="111",.devfd=1,.userfd=2};
//     hashmap_put(map, data1.devid, data1);

//     data_t data2={.devid="222",.devfd=3,.userfd=4};
//     hashmap_put(map, data2.devid, data2);

//     printf("map.size=[%d]\n", hashmap_size(map));
    
//     data_t data3={.devid="222",.devfd=5,.userfd=6};
//     hashmap_put(map, data3.devid, data3);
    
//     printf("map.size=[%d]\n", hashmap_size(map));
//     data_t* data = hashmap_get(map, "111");
//     printf("devid=[%s], devfd=[%d], userfd=[%d]\n", data->devid, data->devfd, data->userfd);
//     data = hashmap_get(map, "222");
//     printf("devid=[%s], devfd=[%d], userfd=[%d]\n", data->devid, data->devfd, data->userfd);

//     hashmap_remove(map, "111");
//     printf("map.size=[%d]\n", hashmap_size(map));


//     hashmap_destroy(map);

//     return 0;
// }